/**
 * 紫微斗数命盘计算核心逻辑
 * 
 * 注意：此文件实现了紫微斗数命盘计算的基本功能，
 * 但为了简化实现，某些计算使用了近似算法，
 * 实际应用中可能需要更复杂的计算来提高准确性。
 */

// 天干地支
const HEAVENLY_STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
const EARTHLY_BRANCHES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];

// 十二宫名称
const PALACE_NAMES = [
  '命宫', '兄弟宫', '夫妻宫', '子女宫',
  '财帛宫', '疾厄宫', '迁移宫', '交友宫',
  '官禄宫', '田宅宫', '福德宫', '父母宫'
];

// 主星列表
const MAIN_STARS = [
  '紫微', '天机', '太阳', '武曲', '天同',
  '廉贞', '天府', '太阴', '贪狼', '巨门',
  '天相', '天梁', '七杀', '破军'
];

// 辅星列表
const SECONDARY_STARS = [
  '文昌', '文曲', '禄存', '天马', '擎羊',
  '陀罗', '火星', '铃星', '地空', '地劫',
  '左辅', '右弼', '天魁', '天钺', '禄神',
  '天官', '天福', '台辅', '封诰'
];

// 五行纳音对应表
const WUXING_NAYIN = {
  '甲子': '海中金', '乙丑': '海中金', '丙寅': '炉中火', '丁卯': '炉中火',
  '戊辰': '大林木', '己巳': '大林木', '庚午': '路旁土', '辛未': '路旁土',
  '壬申': '剑锋金', '癸酉': '剑锋金', '甲戌': '山头火', '乙亥': '山头火',
  '丙子': '涧下水', '丁丑': '涧下水', '戊寅': '城头土', '己卯': '城头土',
  '庚辰': '白蜡金', '辛巳': '白蜡金', '壬午': '杨柳木', '癸未': '杨柳木',
  '甲申': '泉中水', '乙酉': '泉中水', '丙戌': '屋上土', '丁亥': '屋上土',
  '戊子': '霹雳火', '己丑': '霹雳火', '庚寅': '松柏木', '辛卯': '松柏木',
  '壬辰': '长流水', '癸巳': '长流水', '甲午': '沙中金', '乙未': '沙中金',
  '丙申': '山下火', '丁酉': '山下火', '戊戌': '平地木', '己亥': '平地木',
  '庚子': '壁上土', '辛丑': '壁上土', '壬寅': '金箔金', '癸卯': '金箔金',
  '甲辰': '覆灯火', '乙巳': '覆灯火', '丙午': '天河水', '丁未': '天河水',
  '戊申': '大驿土', '己酉': '大驿土', '庚戌': '钗钏金', '辛亥': '钗钏金',
  '壬子': '桑柘木', '癸丑': '桑柘木', '甲寅': '大溪水', '乙卯': '大溪水',
  '丙辰': '沙中土', '丁巳': '沙中土', '戊午': '天上火', '己未': '天上火',
  '庚申': '石榴木', '辛酉': '石榴木', '壬戌': '大海水', '癸亥': '大海水'
};

// 神煞列表
const SHEN_SHA = [
  '天德', '月德', '天才', '天寿', '天医',
  '解神', '天巫', '天月', '天伤', '天使',
  '天官', '天福', '天厨', '天空', '天刑',
  '天姚', '天马', '天贵', '天羊', '天虎'
];

/**
 * 计算紫微斗数命盘
 * @param {string} name - 姓名
 * @param {string} gender - 性别 ('male'/'female')
 * @param {number|string} birthYear - 出生年
 * @param {number|string} birthMonth - 出生月
 * @param {number|string} birthDay - 出生日
 * @param {number|string} birthHour - 出生时辰 (1-12)
 * @param {string} birthSystem - 历法 ('solar'/'lunar')
 * @param {number|string} currentYear - 预测年份
 * @returns {Object} 命盘数据
 */
export function calculateZiWeiChart(name, gender, birthYear, birthMonth, birthDay, birthHour, birthSystem, currentYear) {
  try {
    // 参数预处理和验证
    const processedParams = validateAndProcessParams(
      name, gender, birthYear, birthMonth, birthDay, birthHour, birthSystem, currentYear
    );
    
    if (processedParams.error) {
      console.error(`参数错误: ${processedParams.message}`);
      return {
        error: true,
        message: processedParams.message,
        personalInfo: {
          name, gender, birthYear, birthMonth, birthDay, birthHour, birthSystem
        }
      };
    }
    
    // 使用处理后的参数
    birthYear = processedParams.birthYear;
    birthMonth = processedParams.birthMonth;
    birthDay = processedParams.birthDay;
    birthHour = processedParams.birthHour;
    currentYear = processedParams.currentYear;
    
    // 1. 确定命宫位置
    const mingGongPosition = calculateMingGong(birthMonth, birthHour);
    
    // 2. 安十二宫
    const palaces = arrangeTwelvePalaces(mingGongPosition);
    
    // 3. 安星曜
    const stars = arrangeStars(birthYear, birthMonth, birthDay, birthHour, gender);
    
    // 4. 计算大限
    const daXian = calculateDaXian(gender, birthYear, birthMonth, birthDay, mingGongPosition);
    
    // 5. 计算流年
    const liuNian = calculateLiuNian(currentYear, gender, birthYear, birthMonth, birthDay, mingGongPosition);
    
    // 6. 计算铁板神术预测数据
    const yearGanZhi = calculateGanZhi(birthYear, 'year');
    const monthGanZhi = calculateGanZhi(birthMonth, 'month', birthYear);
    const dayGanZhi = calculateGanZhi(birthDay, 'day', birthYear, birthMonth);
    const hourGanZhi = calculateGanZhi(birthHour, 'hour', birthYear, birthMonth, birthDay);

    const tieBanPrediction = {
      yearNayin: WUXING_NAYIN[yearGanZhi] || '',
      monthNayin: WUXING_NAYIN[monthGanZhi] || '',
      dayNayin: WUXING_NAYIN[dayGanZhi] || '',
      hourNayin: WUXING_NAYIN[hourGanZhi] || '',
      shenSha: calculateShenShaPositions(birthYear, birthMonth, birthDay, birthHour, gender)
    };

    // 7. 组合命盘数据
    return {
      mingGongPosition,
      palaces,
      stars,
      daXian,
      liuNian,
      tieBanPrediction,
      personalInfo: {
        name,
        gender,
        birthYear,
        birthMonth,
        birthDay,
        birthHour,
        birthSystem
      }
    };
  } catch (error) {
    console.error(`命盘计算错误: ${error.message}`);
    
    // 返回错误信息，但仍保留用户输入的个人信息
    return {
      error: true,
      message: error.message,
      personalInfo: {
        name,
        gender,
        birthYear,
        birthMonth,
        birthDay,
        birthHour,
        birthSystem
      }
    };
  }
}

/**
 * 验证并处理输入参数
 * @param {string} name - 姓名
 * @param {string} gender - 性别
 * @param {number|string} birthYear - 出生年
 * @param {number|string} birthMonth - 出生月
 * @param {number|string} birthDay - 出生日
 * @param {number|string} birthHour - 出生时辰
 * @param {string} birthSystem - 历法
 * @param {number|string} currentYear - 预测年份
 * @returns {Object} 处理后的参数或错误信息
 */
function validateAndProcessParams(name, gender, birthYear, birthMonth, birthDay, birthHour, birthSystem, currentYear) {
  try {
    // 转换数值参数
    const year = parseInt(birthYear);
    const month = parseInt(birthMonth);
    const day = parseInt(birthDay);
    const hour = parseInt(birthHour);
    const predYear = parseInt(currentYear);
    
    // 验证姓名
    if (!name || typeof name !== 'string') {
      return { error: true, message: '请提供有效的姓名' };
    }
    
    // 验证性别
    if (gender !== 'male' && gender !== 'female') {
      return { error: true, message: '性别必须为 male 或 female' };
    }
    
    // 验证年份
    if (isNaN(year) || year < 1900 || year > 2100) {
      return { error: true, message: '出生年份必须为1900-2100之间的数值' };
    }
    
    // 验证月份
    if (isNaN(month) || month < 1 || month > 12) {
      return { error: true, message: '出生月份必须为1-12之间的数值' };
    }
    
    // 验证日期
    if (isNaN(day) || day < 1 || day > 31) {
      return { error: true, message: '出生日必须为1-31之间的数值' };
    }
    
    // 验证时辰 - 特殊处理，如果NaN或超出范围，使用默认值1
    let validHour = hour;
    if (isNaN(hour) || hour < 1 || hour > 12) {
      console.warn(`出生时辰 ${birthHour} 无效，使用默认值1`);
      validHour = 1;
    }
    
    // 验证历法
    if (birthSystem !== 'solar' && birthSystem !== 'lunar') {
      return { error: true, message: '历法必须为 solar 或 lunar' };
    }
    
    // 验证预测年份
    if (isNaN(predYear) || predYear < year || predYear > 2100) {
      return { error: true, message: '预测年份必须为出生年份至2100之间的数值' };
    }
    
    // 返回处理后的参数
    return {
      error: false,
      birthYear: year,
      birthMonth: month,
      birthDay: day,
      birthHour: validHour,
      currentYear: predYear
    };
    
  } catch (error) {
    return { error: true, message: `参数处理错误: ${error.message}` };
  }
}

/**
 * 计算命宫位置
 * @param {number} month - 出生月份
 * @param {number} hour - 出生时辰 (1-12)
 * @returns {number} 命宫位置 (1-12)
 */
function calculateMingGong(month, hour) {
  try {
    // 紫微斗数命宫公式：以寅宫起子月，顺数至生月，再逆数至生时
    let position = 3; // 寅宫起始位置为3
    
    // 确保输入是数字并且在有效范围内
    const validMonth = isNaN(parseInt(month)) ? 1 : 
                       Math.max(1, Math.min(12, parseInt(month)));
    const validHour = isNaN(parseInt(hour)) ? 1 : 
                      Math.max(1, Math.min(12, parseInt(hour)));
    
    // 从寅宫顺数至生月
    position = (position + validMonth - 1) % 12;
    if (position === 0) position = 12;
    
    // 从生月宫逆数至生时
    position = (position - validHour + 12) % 12;
    if (position === 0) position = 12;
    
    return position;
  } catch (error) {
    console.error(`命宫计算错误: ${error.message}`);
    return 3; // 出错时返回寅宫位置
  }
}

/**
 * 安十二宫
 * @param {number} mingGongPosition - 命宫位置
 * @returns {Array} 十二宫位数据
 */
function arrangeTwelvePalaces(mingGongPosition) {
  try {
    // 从命宫位置开始排列十二宫
    const palaces = [];
    
    for (let i = 0; i < 12; i++) {
      const position = (mingGongPosition + i) % 12 || 12;
      const palace = {
        position: position,
        name: PALACE_NAMES[i],
        stars: [] // 将在安星曜步骤中填充
      };
      palaces.push(palace);
    }
    
    return palaces;
  } catch (error) {
    console.error(`安十二宫错误: ${error.message}`);
    return []; // 出错时返回空数组
  }
}

/**
 * 安星曜
 * @param {number} year - 出生年
 * @param {number} month - 出生月
 * @param {number} day - 出生日
 * @param {number} hour - 出生时辰
 * @param {string} gender - 性别
 * @returns {Object} 星曜位置数据
 */
function arrangeStars(year, month, day, hour, gender) {
  try {
    // 以下为紫微斗数星曜安排的简化算法
    // 实际应用中应使用完整的紫微斗数算法
    
    // 确保输入是数字
    year = parseInt(year);
    month = parseInt(month);
    day = parseInt(day);
    hour = parseInt(hour);
    
    // 计算紫微星位置（简化版）
    const ziWeiPosition = calculateZiWeiPosition(year, month, day);
    
    // 根据紫微星位置，安排其他主星
    const starPositions = {};
    
    // 紫微星系安星（简化版）
    starPositions['紫微'] = ziWeiPosition;
    starPositions['天机'] = (ziWeiPosition + 1) % 12 || 12;
    starPositions['太阳'] = (ziWeiPosition + 3) % 12 || 12;
    starPositions['武曲'] = (ziWeiPosition + 4) % 12 || 12;
    starPositions['天同'] = (ziWeiPosition + 5) % 12 || 12;
    starPositions['廉贞'] = (ziWeiPosition + 8) % 12 || 12;
    
    // 天府星系安星（简化版）
    const tianFuPosition = (12 - ziWeiPosition + 1) % 12 || 12;
    starPositions['天府'] = tianFuPosition;
    starPositions['太阴'] = (tianFuPosition + 1) % 12 || 12;
    starPositions['贪狼'] = (tianFuPosition + 2) % 12 || 12;
    starPositions['巨门'] = (tianFuPosition + 3) % 12 || 12;
    starPositions['天相'] = (tianFuPosition + 4) % 12 || 12;
    starPositions['天梁'] = (tianFuPosition + 5) % 12 || 12;
    starPositions['七杀'] = (tianFuPosition + 6) % 12 || 12;
    starPositions['破军'] = (tianFuPosition + 10) % 12 || 12;
    
    // 安辅星（简化版）
    // 文昌、文曲
    starPositions['文昌'] = ((day % 12) + 4) % 12 || 12;
    starPositions['文曲'] = ((14 - (day % 12)) % 12) || 12;
    
    // 左辅、右弼
    starPositions['左辅'] = ((month + 4) % 12) || 12;
    starPositions['右弼'] = ((12 - month + 3) % 12) || 12;
    
    // 禄存
    const birthYearStem = calculateYearStem(year);
    starPositions['禄存'] = getLuCunPosition(birthYearStem);
    
    // 简化其他辅星位置
    SECONDARY_STARS.forEach((star, index) => {
      if (!starPositions[star]) {
        starPositions[star] = ((index + parseInt(day)) % 12) || 12;
      }
    });
    
    // 计算四化星
    const yearGanZhi = calculateGanZhi(year, 'year');
    const yearGan = yearGanZhi.charAt(0);
    
    // 四化星所在星曜
    const huaLuStar = getHuaLuStar(yearGan);
    const huaQuanStar = getHuaQuanStar(yearGan);
    const huaKeStar = getHuaKeStar(yearGan);
    const huaJiStar = getHuaJiStar(yearGan);
    
    // 设置四化位置
    if (starPositions[huaLuStar]) {
      starPositions['化禄'] = starPositions[huaLuStar];
    }
    
    if (starPositions[huaQuanStar]) {
      starPositions['化权'] = starPositions[huaQuanStar];
    }
    
    if (starPositions[huaKeStar]) {
      starPositions['化科'] = starPositions[huaKeStar];
    }
    
    if (starPositions[huaJiStar]) {
      starPositions['化忌'] = starPositions[huaJiStar];
    }
    
    // 计算铁板神术神煞位置
    const shenShaPositions = calculateShenShaPositions(year, month, day, hour, gender);
    
    // 合并神煞位置到星曜位置
    Object.assign(starPositions, shenShaPositions);
    
    return starPositions;
  } catch (error) {
    console.error(`安星曜错误: ${error.message}`);
    return {}; // 出错时返回空对象
  }
}

/**
 * 计算铁板神术神煞位置
 * @param {number} year - 出生年
 * @param {number} month - 出生月
 * @param {number} day - 出生日
 * @param {number} hour - 出生时辰
 * @param {string} gender - 性别
 * @returns {Object} 神煞位置数据
 */
function calculateShenShaPositions(year, month, day, hour, gender) {
  try {
    const positions = {};
    
    // 确保输入是数字
    year = parseInt(year);
    month = parseInt(month);
    day = parseInt(day);
    hour = parseInt(hour);
    
    const yearGanZhi = calculateGanZhi(year, 'year');
    const monthGanZhi = calculateGanZhi(month, 'month', year);
    const dayGanZhi = calculateGanZhi(day, 'day', year, month);
    const hourGanZhi = calculateGanZhi(hour, 'hour', year, month, day);
    
    // 计算纳音五行
    const yearNayin = WUXING_NAYIN[yearGanZhi] || '';
    const monthNayin = WUXING_NAYIN[monthGanZhi] || '';
    const dayNayin = WUXING_NAYIN[dayGanZhi] || '';
    const hourNayin = WUXING_NAYIN[hourGanZhi] || '';
    
    // 计算天德神煞
    positions['天德'] = calculateTianDe(yearGanZhi);
    
    // 计算月德神煞
    positions['月德'] = calculateYueDe(monthGanZhi);
    
    // 计算天才神煞
    positions['天才'] = calculateTianCai(dayGanZhi, gender);
    
    // 计算天寿神煞
    positions['天寿'] = calculateTianShou(hourGanZhi);
    
    // 根据纳音五行计算其他神煞
    SHEN_SHA.forEach(shenSha => {
      if (!positions[shenSha]) {
        positions[shenSha] = calculateShenShaByNayin(
          shenSha,
          yearNayin,
          monthNayin,
          dayNayin,
          hourNayin,
          gender
        );
      }
    });
    
    return positions;
  } catch (error) {
    console.error(`神煞位置计算错误: ${error.message}`);
    return {}; // 出错时返回空对象
  }
}

/**
 * 计算天德神煞位置
 * @param {string} yearGanZhi - 年干支
 * @returns {number} 天德神煞位置
 */
function calculateTianDe(yearGanZhi) {
  try {
    const gan = yearGanZhi.charAt(0);
    const positions = {
      '甲': 1, '乙': 2, '丙': 3, '丁': 4, '戊': 5,
      '己': 6, '庚': 7, '辛': 8, '壬': 9, '癸': 10
    };
    return positions[gan] || 1;
  } catch (error) {
    return 1; // 出错时返回默认位置
  }
}

/**
 * 计算月德神煞位置
 * @param {string} monthGanZhi - 月干支
 * @returns {number} 月德神煞位置
 */
function calculateYueDe(monthGanZhi) {
  try {
    const zhi = monthGanZhi.charAt(1);
    const positions = {
      '子': 11, '丑': 12, '寅': 1, '卯': 2, '辰': 3, '巳': 4,
      '午': 5, '未': 6, '申': 7, '酉': 8, '戌': 9, '亥': 10
    };
    return positions[zhi] || 1;
  } catch (error) {
    return 1; // 出错时返回默认位置
  }
}

/**
 * 计算天才神煞位置
 * @param {string} dayGanZhi - 日干支
 * @param {string} gender - 性别
 * @returns {number} 天才神煞位置
 */
function calculateTianCai(dayGanZhi, gender) {
  try {
    const gan = dayGanZhi.charAt(0);
    const base = {
      '甲': 1, '乙': 2, '丙': 3, '丁': 4, '戊': 5,
      '己': 6, '庚': 7, '辛': 8, '壬': 9, '癸': 10
    }[gan] || 1;
    
    // 男顺女逆
    return gender === 'male' ? base : (12 - base + 1);
  } catch (error) {
    return 1; // 出错时返回默认位置
  }
}

/**
 * 计算天寿神煞位置
 * @param {string} hourGanZhi - 时干支
 * @returns {number} 天寿神煞位置
 */
function calculateTianShou(hourGanZhi) {
  try {
    const zhi = hourGanZhi.charAt(1);
    const positions = {
      '子': 1, '丑': 2, '寅': 3, '卯': 4, '辰': 5, '巳': 6,
      '午': 7, '未': 8, '申': 9, '酉': 10, '戌': 11, '亥': 12
    };
    return positions[zhi] || 1;
  } catch (error) {
    return 1; // 出错时返回默认位置
  }
}

/**
 * 根据纳音五行计算神煞位置
 * @param {string} shenSha - 神煞名称
 * @param {string} yearNayin - 年纳音
 * @param {string} monthNayin - 月纳音
 * @param {string} dayNayin - 日纳音
 * @param {string} hourNayin - 时纳音
 * @param {string} gender - 性别
 * @returns {number} 神煞位置
 */
function calculateShenShaByNayin(shenSha, yearNayin, monthNayin, dayNayin, hourNayin, gender) {
  try {
    // 根据神煞特性和纳音五行计算位置
    // 这里使用简化算法，实际应用中需要更复杂的计算规则
    const nayinType = yearNayin ? yearNayin.slice(-1) : '金'; // 取纳音五行类型（金木水火土），默认为金
    
    // 根据五行生克关系和神煞特性确定基础位置
    const basePosition = {
      '金': 1, '木': 3, '水': 5, '火': 7, '土': 9
    }[nayinType] || 1;
    
    // 根据神煞类型调整位置
    let adjustment = 0;
    switch (shenSha) {
      case '天巫':
        adjustment = monthNayin?.includes('水') ? 1 : 0;
        break;
      case '天月':
        adjustment = dayNayin?.includes('金') ? 2 : 0;
        break;
      case '天空':
        adjustment = hourNayin?.includes('火') ? -1 : 0;
        break;
      default:
        adjustment = 0;
    }
    
    // 计算最终位置
    let position = (basePosition + adjustment + 12) % 12;
    if (position === 0) position = 12;
    
    // 部分神煞需要根据性别调整方向
    if (['天马', '天贵', '天羊'].includes(shenSha) && gender === 'female') {
      position = 13 - position;
    }
    
    return position;
  } catch (error) {
    return 1; // 出错时返回默认位置
  }
}

/**
 * 计算紫微星位置（简化版）
 * @param {number} year - 出生年
 * @param {number} month - 出生月
 * @param {number} day - 出生日
 * @returns {number} 紫微星位置 (1-12)
 */
function calculateZiWeiPosition(year, month, day) {
  try {
    // 确保输入是数字
    year = parseInt(year);
    month = parseInt(month);
    day = parseInt(day);
    
    // 将日数换算成局数（甲局、乙局等）
    let level = day % 5;
    if (level === 0) level = 5;
    
    // 根据局数确定紫微星位置（简化版）
    const positions = {
      1: 1, // 水二局，紫微在寅
      2: 3, // 木三局，紫微在辰
      3: 5, // 金四局，紫微在午
      4: 7, // 土五局，紫微在申
      5: 9  // 火六局，紫微在戌
    };
    
    return positions[level] || 1;
  } catch (error) {
    console.error(`紫微星位置计算错误: ${error.message}`);
    return 1; // 出错时返回默认位置
  }
}

/**
 * 计算年干
 * @param {number} year - 年份
 * @returns {string} 天干
 */
function calculateYearStem(year) {
  try {
    // 确保输入是数字
    year = parseInt(year);
    
    // 1900年为庚子年，天干为庚（索引为6）
    const index = (year - 1900 + 6) % 10;
    return HEAVENLY_STEMS[index];
  } catch (error) {
    console.error(`年干计算错误: ${error.message}`);
    return '甲'; // 出错时返回甲
  }
}

/**
 * 计算禄存星位置
 * @param {string} yearStem - 年干
 * @returns {number} 禄存星位置 (1-12)
 */
function getLuCunPosition(yearStem) {
  try {
    // 禄存星位置与年干的对应关系
    const positions = {
      '甲': 3, // 寅宫
      '乙': 4, // 卯宫
      '丙': 6, // 巳宫
      '丁': 7, // 午宫
      '戊': 6, // 巳宫
      '己': 7, // 午宫
      '庚': 9, // 申宫
      '辛': 10, // 酉宫
      '壬': 12, // 亥宫
      '癸': 1  // 子宫
    };
    
    return positions[yearStem] || 3;
  } catch (error) {
    return 3; // 出错时返回默认位置
  }
}

/**
 * 计算干支
 * @param {number} num - 数值
 * @param {string} type - 类型 ('year', 'month', 'day', 'hour')
 * @param {number} [refYear] - 参考年份
 * @param {number} [refMonth] - 参考月份
 * @param {number} [refDay] - 参考日期
 * @returns {string} 干支组合
 */
function calculateGanZhi(num, type, refYear, refMonth, refDay) {
  try {
    // 确保输入是数字
    num = parseInt(num);
    if (refYear) refYear = parseInt(refYear);
    if (refMonth) refMonth = parseInt(refMonth);
    if (refDay) refDay = parseInt(refDay);
    
    let stemIndex = 0;
    let branchIndex = 0;
    
    switch (type) {
      case 'year':
        // 年干支计算，以1900年为 庚子年 为基础
        stemIndex = (num - 1900 + 6) % 10;
        branchIndex = (num - 1900 + 0) % 12;
        break;
      case 'month':
        // 月干支计算 (简化)
        const yearStem = (refYear - 1900 + 6) % 10;
        stemIndex = (yearStem * 2 + num) % 10;
        branchIndex = (num + 1) % 12;
        break;
      case 'day':
        // 日干支计算 (简化)
        try {
          const baseDate = new Date(1900, 0, 1);
          const targetDate = new Date(refYear, refMonth - 1, refDay);
          const diffDays = Math.floor((targetDate - baseDate) / (24 * 60 * 60 * 1000));
          stemIndex = (diffDays + 9) % 10;
          branchIndex = (diffDays + 3) % 12;
        } catch (e) {
          // 日期计算错误时使用备选方案
          stemIndex = (refDay % 10);
          branchIndex = (refDay % 12);
        }
        break;
      case 'hour':
        // 时干支计算 (简化)
        branchIndex = (num - 1) % 12;
        // 根据日干确定时干
        if (refDay && refMonth && refYear) {
          try {
            const dayGanZhi = calculateGanZhi(refDay, 'day', refYear, refMonth);
            if (dayGanZhi && typeof dayGanZhi === 'string') {
              const dayStem = dayGanZhi.charAt(0);
              const dayStemIndex = HEAVENLY_STEMS.indexOf(dayStem);
              if (dayStemIndex !== -1) {
                stemIndex = (dayStemIndex * 2 + branchIndex) % 10;
              }
            }
          } catch (e) {
            // 日干计算错误时使用备选方案
            stemIndex = branchIndex % 10;
          }
        }
        
        // 如果无法计算日干或计算失败，使用默认计算方式
        if (stemIndex === 0 && branchIndex !== 0) {
          stemIndex = (branchIndex) % 10;
        }
        break;
      default:
        // 未知类型时使用默认值
        stemIndex = 0;
        branchIndex = 0;
    }
    
    // 处理负数索引
    if (stemIndex < 0) stemIndex += 10;
    if (branchIndex < 0) branchIndex += 12;
    
    // 确保索引在有效范围内
    stemIndex = stemIndex % 10;
    branchIndex = branchIndex % 12;
    
    return HEAVENLY_STEMS[stemIndex] + EARTHLY_BRANCHES[branchIndex];
  } catch (error) {
    console.error(`干支计算错误: ${error.message}`);
    // 出错时返回甲子
    return HEAVENLY_STEMS[0] + EARTHLY_BRANCHES[0];
  }
}

/**
 * 获取化禄星
 * @param {string} yearGan - 年干
 * @returns {string} 化禄所在星曜
 */
function getHuaLuStar(yearGan) {
  const huaLuStars = {
    '甲': '廉贞', '乙': '天机', '丙': '天同', '丁': '太阴',
    '戊': '贪狼', '己': '武曲', '庚': '太阳', '辛': '巨门',
    '壬': '天机', '癸': '太阴'
  };
  
  return huaLuStars[yearGan] || '廉贞';
}

/**
 * 获取化权星
 * @param {string} yearGan - 年干
 * @returns {string} 化权所在星曜
 */
function getHuaQuanStar(yearGan) {
  const huaQuanStars = {
    '甲': '破军', '乙': '天梁', '丙': '紫微', '丁': '七杀',
    '戊': '武曲', '己': '贪狼', '庚': '天府', '辛': '天相',
    '壬': '天同', '癸': '太阳'
  };
  
  return huaQuanStars[yearGan] || '破军';
}

/**
 * 获取化科星
 * @param {string} yearGan - 年干
 * @returns {string} 化科所在星曜
 */
function getHuaKeStar(yearGan) {
  const huaKeStars = {
    '甲': '武曲', '乙': '太阴', '丙': '天机', '丁': '天梁',
    '戊': '紫微', '己': '巨门', '庚': '贪狼', '辛': '太阴',
    '壬': '文昌', '癸': '文曲'
  };
  
  return huaKeStars[yearGan] || '武曲';
}

/**
 * 获取化忌星
 * @param {string} yearGan - 年干
 * @returns {string} 化忌所在星曜
 */
function getHuaJiStar(yearGan) {
  const huaJiStars = {
    '甲': '巨门', '乙': '贪狼', '丙': '廉贞', '丁': '破军',
    '戊': '巨门', '己': '天梁', '庚': '七杀', '辛': '武曲',
    '壬': '廉贞', '癸': '贪狼'
  };
  
  return huaJiStars[yearGan] || '巨门';
}

/**
 * 计算大限
 * @param {string} gender - 性别
 * @param {number} birthYear - 出生年
 * @param {number} birthMonth - 出生月
 * @param {number} birthDay - 出生日
 * @param {number} mingGongPosition - 命宫位置
 * @returns {Array} 大限数据
 */
function calculateDaXian(gender, birthYear, birthMonth, birthDay, mingGongPosition) {
  try {
    // 确保输入是数字
    birthYear = parseInt(birthYear);
    
    // 大限计算（简化版）
    // 每个大限为10年，男顺女逆
    const daXianList = [];
    const startAge = 1; // 大限起始年龄，男女相同
    const direction = gender === 'male' ? 1 : -1; // 男顺女逆
    
    for (let i = 0; i < 12; i++) {
      const position = ((mingGongPosition + i * direction) % 12 + 12) % 12 || 12;
      const startYear = birthYear + startAge + i * 10;
      const endYear = startYear + 9;
      
      daXianList.push({
        position: position,
        startAge: startAge + i * 10,
        endAge: startAge + (i + 1) * 10 - 1,
        startYear: startYear,
        endYear: endYear
      });
    }
    
    return daXianList;
  } catch (error) {
    console.error(`大限计算错误: ${error.message}`);
    return []; // 出错时返回空数组
  }
}

/**
 * 计算流年
 * @param {number} currentYear - 当前年份
 * @param {string} gender - 性别
 * @param {number} birthYear - 出生年
 * @param {number} birthMonth - 出生月
 * @param {number} birthDay - 出生日
 * @param {number} mingGongPosition - 命宫位置
 * @returns {Object} 流年数据
 */
function calculateLiuNian(currentYear, gender, birthYear, birthMonth, birthDay, mingGongPosition) {
  try {
    // 确保输入是数字
    currentYear = parseInt(currentYear);
    birthYear = parseInt(birthYear);
    
    // 计算虚岁年龄
    const age = currentYear - birthYear + 1;
    
    // 大限方向
    const daXianDirection = gender === 'male' ? 1 : -1;
    
    // 当前处于哪个大限
    const daXianIndex = Math.floor((age - 1) / 10);
    
    // 大限位置
    const daXianPosition = ((mingGongPosition + daXianIndex * daXianDirection) % 12 + 12) % 12 || 12;
    
    // 小限方向（与大限相反）
    const xiaoXianDirection = daXianDirection * -1;
    
    // 小限年位置 = 大限宫 + (年龄 % 10) * 小限方向
    const xiaoXianOffset = (age - 1) % 10;
    const liuNianPosition = ((daXianPosition + xiaoXianOffset * xiaoXianDirection) % 12 + 12) % 12 || 12;
    
    // 流年太岁干支
    const liuNianGanZhi = calculateGanZhi(currentYear, 'year');
    
    return {
      year: currentYear,
      age: age,
      position: liuNianPosition,
      ganZhi: liuNianGanZhi
    };
  } catch (error) {
    console.error(`流年计算错误: ${error.message}`);
    
    // 出错时返回基本信息
    return {
      year: currentYear,
      age: 1,
      position: 1,
      ganZhi: calculateGanZhi(currentYear, 'year')
    };
  }
}